home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 30
/
Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso
/
Aminet
/
dev
/
lang
/
SmallEiffel.lha
/
SmallEiffel
/
lib_se
/
system_tools.e
< prev
next >
Wrap
Text File
|
1998-12-22
|
17KB
|
648 lines
-- This file is part of SmallEiffel The GNU Eiffel Compiler.
-- Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
-- Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
-- http://www.loria.fr/SmallEiffel
-- SmallEiffel is free software; you can redistribute it and/or modify it
-- under the terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 2, or (at your option) any later
-- version. SmallEiffel is distributed in the hope that it will be useful,but
-- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for more details. You should have received a copy of the GNU General
-- Public License along with SmallEiffel; see the file COPYING. If not,
-- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-- Boston, MA 02111-1307, USA.
--
class SYSTEM_TOOLS
--
-- Singleton object to handle system dependant information.
-- This singleton is shared via the GLOBALS.`system_tools' once function.
--
-- Only this object is supposed to handle contents of the `SmallEiffel'
-- system environment variable.
--
-- You may also want to customize this class in order to support a
-- new operating system (please let us know).
--
inherit GLOBALS;
creation make
feature {NONE} -- Currently handled system List :
amiga_system: STRING is "Amiga";
beos_system: STRING is "BeOS";
dos_system: STRING is "DOS";
macintosh_system: STRING is "Macintosh";
os2_system: STRING is "OS2";
unix_system: STRING is "UNIX";
vms_system: STRING is "VMS";
windows_system: STRING is "Windows";
feature {NONE}
system_list: ARRAY[STRING] is
once
Result := << amiga_system,
beos_system,
dos_system,
macintosh_system,
os2_system,
unix_system,
vms_system,
windows_system
>>;
end;
feature {NONE}
system_name: STRING;
sys_directory: STRING;
-- The SmallEiffel/sys directory computed with the value of
-- the environment variable `SmallEiffel'.
-- For example, under UNIX: "/usr/lib/SmallEiffel/sys/"
bin_directory: STRING;
-- For example, under UNIX: "/usr/lib/SmallEiffel/bin/"
feature {NONE}
make is
local
system_se_path: STRING;
i: INTEGER;
do
system_se_path := get_environment_variable(fz_se);
if system_se_path = Void then
system_se_path := fz_se.twin;
system_se_path.to_upper;
system_se_path := get_environment_variable(system_se_path);
if system_se_path = Void then
echo.put_string(
"System environment variable %"SmallEiffel%" not set.%N%
%Trying default value: %"");
system_se_path := "/usr/lib/SmallEiffel/sys/system.se";
echo.put_string(system_se_path);
echo.put_string(fz_03);
end;
end;
if system_se_path.has_suffix(fz_system_se) then
echo.sfr_connect(tmp_file_read,system_se_path);
else
echo.put_string(
"You should update the value of the %"SmallEiffel%" %
%system environment variable.%N%
%Since release -0.79, the %"SmallEiffel%" system %
%environment variable must be the absolute path of %
%the %"system.se%" file.%N%
%For example %"/usr/lib/SmallEiffel/sys/system.se%" %
%under Unix like system.%N");
if system_se_path.has('/') then
echo.put_string("%"Hope this is a Unix like system.%N");
tmp_path.copy(system_se_path);
tmp_path.set_last('/');
tmp_path.append(fz_sys);
tmp_path.extend('/');
tmp_path.append(fz_system_se);
echo.sfr_connect(tmp_file_read,tmp_path);
end;
if not tmp_file_read.is_connected then
if system_se_path.has('\') then
echo.put_string("%"Hope this is a DOS or Windows like system.%N");
tmp_path.copy(system_se_path);
tmp_path.set_last('\');
tmp_path.append(fz_sys);
tmp_path.extend('\');
tmp_path.append(fz_system_se);
echo.sfr_connect(tmp_file_read,tmp_path);
end;
end;
if not tmp_file_read.is_connected then
if system_se_path.has(':') then
echo.put_string("%"Hope this is a Macintosh like system.%N");
tmp_path.copy(system_se_path);
tmp_path.set_last(':');
tmp_path.append(fz_sys);
tmp_path.extend(':');
tmp_path.append(fz_system_se);
echo.sfr_connect(tmp_file_read,tmp_path);
end;
end;
if not tmp_file_read.is_connected then
if system_se_path.has(']') then
echo.put_string("%"Hope this is a VMS system.%N");
tmp_path.copy(system_se_path);
tmp_path.set_last(']');
tmp_path.remove_last(1);
tmp_path.extend('.');
tmp_path.append(fz_sys);
tmp_path.extend(']');
tmp_path.append(fz_system_se);
echo.sfr_connect(tmp_file_read,tmp_path);
end;
end;
if not tmp_file_read.is_connected then
echo.put_string("%"Last chance.%N");
tmp_path.copy(system_se_path);
tmp_path.append(fz_system_se);
echo.sfr_connect(tmp_file_read,tmp_path);
end;
end;
if not tmp_file_read.is_connected then
echo.w_put_string(
"Unable to find file %"system.se%".%N%
%Please, set the environment variable %"SmallEiffel%" %
%with the appropriate absolute path to this file.%N%
%Example for Unix: %"/usr/lib/SmallEiffel/sys/system.se%"%N%
%Example for DOS/Windows: %"C:\SmallEiffel\sys\system.se%"%N");
die_with_code(exit_failure_code);
end;
tmp_file_read.read_line;
system_name := tmp_file_read.last_string;
i := system_list.index_of(system_name);
if i > system_list.upper then
echo.w_put_string("Unknown system name in file%N%"");
echo.w_put_string(tmp_file_read.path);
echo.w_put_string("%".%NCurrently handled system names :%N");
from
i := 1;
until
i > system_list.upper
loop
echo.w_put_string(system_list.item(i));
echo.w_put_character('%N');
i := i + 1;
end;
die_with_code(exit_failure_code);
else
system_name := system_list.item(i);
echo.put_string("System is %"");
echo.put_string(system_name);
echo.put_string(fz_b0);
end;
sys_directory := tmp_file_read.path.twin;
sys_directory.remove_suffix(fz_system_se);
tmp_file_read.disconnect;
bin_directory := sys_directory.twin;
parent_directory(bin_directory);
add_directory(bin_directory,fz_bin);
end;
feature {COMPILE}
compile_to_c_in(command: STRING) is
-- Append the system command call
do
if windows_system /= system_name then
command.append(bin_directory);
end;
command.append(us_compile_to_c);
command.append(x_suffix);
end;
feature {COMPILE}
clean_in(command: STRING) is
do
if windows_system /= system_name then
command.append(bin_directory);
end;
command.append(fz_clean);
command.append(x_suffix);
end;
feature {C_PRETTY_PRINTER}
first_line_of_sys_file(name: STRING): STRING is
-- Create a new STRING which is the contents of the first
-- line of the corresponding SmallEiffel/sys/ directory.
do
tmp_path.copy(sys_directory);
tmp_path.append(name);
tmp_path.append(system_name);
echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
tmp_file_read.read_line;
Result := tmp_file_read.last_string.twin;
tmp_file_read.disconnect;
end;
feature {C_PRETTY_PRINTER}
sys_runtime(name: STRING; suffix: CHARACTER) is
-- Prepare `tmp_file_read' to access the corresponding file
-- in the SmallEiffel/sys/runtime directory.
require
name /= Void;
suffix = 'c' or suffix = 'h'
do
tmp_path.copy(sys_directory);
add_directory(tmp_path,fz_runtime);
tmp_path.append(name);
tmp_path.extend('.');
tmp_path.extend(suffix);
echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
ensure
tmp_file_read.is_connected
end;
feature {COMPILE,CLEAN}
remove_make_script: STRING is
-- Compute the corresponding make file script and remove
-- the old one if any.
do
Result := path_h;
Result.remove_suffix(h_suffix);
Result.append(make_suffix);
echo.file_removing(Result);
end;
feature {C_PRETTY_PRINTER}
path_h: STRING is
-- Create a new STRING which is the name of the
-- main *.h file.
do
Result := run_control.root_class.twin;
Result.to_lower;
if dos_system = system_name then
from
until
Result.count <= 4
loop
Result.remove_last(1);
end;
end;
Result.append(h_suffix);
end;
feature {SMALL_EIFFEL}
read_loading_path_in(lp: ARRAY[STRING]) is
do
loading_path_add(lp,fz_loadpath_se,1);
tmp_path.copy(sys_directory);
tmp_path.append("loadpath.");
tmp_path.append(system_name);
loading_path_add(lp,tmp_path,1);
end;
feature {NONE}
fz_loadpath_se: STRING is "loadpath.se";
loading_path_add(lp: ARRAY[STRING]; path: STRING; level: INTEGER) is
local
file: STD_FILE_READ;
line: STRING;
do
if level > 5 or else lp.count > 1024 then
echo.w_put_string(
"Eiffel source loading path too long or infinite %
%loadpath.se includes.%N");
!!line.make(1024);
append_lp_in(line,lp);
echo.w_put_string(line);
die_with_code(exit_failure_code);
end;
!!file.make;
echo.sfr_connect(file,path);
if file.is_connected then
from
echo.put_string("Append contents of %"");
echo.put_string(path);
echo.put_string("%" to loading path.%N");
until
file.end_of_input
loop
file.read_line;
line := file.last_string.twin;
if line.has_suffix(fz_loadpath_se) then
loading_path_add(lp,line,level + 1);
elseif not line.empty then
lp.add_last(line);
end;
end;
file.disconnect;
end;
end;
feature {SMALL_EIFFEL}
append_lp_in(str: STRING; lp: ARRAY[STRING]) is
local
i: INTEGER;
sed: STRING;
do
str.append("%NLoading path is:%N[%N");
from
i := lp.lower;
until
i > lp.upper
loop
str.extend(' ');
str.extend('%"');
str.append(lp.item(i));
str.extend('%"');
str.extend('%N');
i := i + 1;
end;
str.append("]%NEnvironment Variable %"SmallEiffel%" is:%N");
sed := get_environment_variable(fz_se);
if sed = Void then
str.append("not set.%N");
else
str.append(" %"");
str.append(sed);
str.append("%".%N");
end;
end;
feature {GC_HANDLER}
put_mark_stack_and_registers is
-- Add customized assembly code to mark registers.
local
architecture: STRING;
do
tmp_path.copy(sys_directory);
tmp_path.append(fz_gc);
echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
architecture := echo.read_word_in(tmp_file_read);
tmp_file_read.disconnect;
if us_none.is_equal(architecture) then
eh.append(
"Assembly Code for Garbage Collector not selected in %"");
eh.append(tmp_path);
eh.append(
"%". Default generic (hazardous) C code is provided.");
eh.print_as_warning;
architecture := "generic.c";
end;
tmp_path.copy(sys_directory);
add_directory(tmp_path,fz_gc_lib);
tmp_path.append(architecture);
echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
cpp.put_c_file(tmp_file_read);
end;
feature {NONE}
add_directory(path, dir: STRING) is
require
path.count > 0;
dir.count > 0
do
if slash_separator then
path.set_last('/');
path.append(dir);
path.set_last('/');
elseif backslash_separator then
path.set_last('\');
path.append(dir);
path.set_last('\');
elseif colon_separator then
path.set_last(':');
path.append(dir);
path.set_last(':');
elseif vms_system = system_name then
path.set_last(']');
path.remove_last(1);
path.set_last('.');
path.append(dir);
path.set_last(']');
end;
end;
feature {NONE}
parent_directory(path: STRING) is
-- Remove the last sub-directory of `path' (assume `path' is
-- a combination of more than one directory).
require
path.count > 0
do
if slash_separator then
from
path.remove_last(1);
until
path.last = '/'
loop
path.remove_last(1);
end;
elseif backslash_separator then
from
path.remove_last(1);
until
path.last = '\'
loop
path.remove_last(1);
end;
elseif colon_separator then
from
path.remove_last(1);
until
path.last = ':'
loop
path.remove_last(1);
end;
elseif vms_system = system_name then
from
path.remove_last(1);
until
path.last = '.'
loop
path.remove_last(1);
end;
path.remove_last(1);
path.extend(']');
end;
ensure
path.count > 0;
path.count < (old path.count)
end;
feature {NONE}
slash_separator: BOOLEAN is
do
if unix_system = system_name then
Result := true;
elseif amiga_system = system_name then
Result := true;
end;
end;
feature {NONE}
backslash_separator: BOOLEAN is
do
if windows_system = system_name then
Result := true;
elseif dos_system = system_name then
Result := true;
elseif os2_system = system_name then
Result := true;
end;
end;
feature {NONE}
colon_separator: BOOLEAN is
do
if macintosh_system = system_name then
Result := true;
elseif beos_system = system_name then
Result := true;
end;
end;
feature {SHORT_PRINT}
format_directory(format: STRING): STRING is
require
format /= Void
do
!!Result.make(sys_directory.count + 10);
Result.copy(sys_directory);
parent_directory(Result);
add_directory(Result,"short");
add_directory(Result,format);
end;
feature
bad_use_exit(command_name: STRING) is
require
command_name /= Void
do
echo.w_put_string("Bad use of command `");
echo.w_put_string(command_name);
echo.w_put_string("'.%N");
tmp_path.copy(sys_directory);
parent_directory(tmp_path);
add_directory(tmp_path,"man");
tmp_path.append(command_name);
tmp_path.append(help_suffix);
echo.w_put_string("See docmentation in file:%N ");
echo.w_put_string(tmp_path);
echo.w_put_character('%N');
die_with_code(exit_failure_code);
end;
feature {JVM}
class_file_path(path, directory, class_file_name: STRING) is
-- Prepare `path' using `directory' and `class_file_name'.
do
path.clear;
if vms_system = system_name then
if directory.first /= '[' then
path.extend('[');
end;
end;
path.append(directory);
if slash_separator then
path.set_last('/');
elseif backslash_separator then
path.set_last('\');
elseif colon_separator then
path.set_last(':');
elseif vms_system = system_name then
path.set_last(']');
end;
path.append(class_file_name);
path.append(class_suffix);
end;
feature {C_PRETTY_PRINTER}
put_c_main_function_type(out_c: STD_FILE_WRITE) is
do
if vms_system = system_name then
out_c.put_string(fz_void);
else
out_c.put_string(fz_int);
end;
end;
feature {C_PRETTY_PRINTER}
strip_executable(command: STRING): BOOLEAN is
require
command /= Void
do
if unix_system = system_name then
Result := true;
command.copy("strip ");
elseif os2_system = system_name then
Result := true;
command.copy("emxbind -qs ");
end;
end;
feature
make_suffix: STRING is
-- Suffix for make file produced by `compile_to_c'.
once
if dos_system = system_name then
Result := ".BAT";
elseif windows_system = system_name then
Result := ".bat";
elseif vms_system = system_name then
Result := ".COM";
elseif os2_system = system_name then
Result := ".CMD";
else
Result := ".make";
end;
end;
feature
x_suffix: STRING is
-- Executable files suffix.
once
if dos_system = system_name or else
vms_system = system_name
then
Result := ".EXE";
elseif os2_system = system_name then
Result := ".exe";
elseif windows_system = system_name then
Result := ".exe";
else
Result := "";
end;
end;
feature
o_suffix_memory: STRING is
-- Object File produced by the C Compiler.
once
!!Result.make(4);
tmp_path.copy(sys_directory);
tmp_path.append("o_suffix.");
tmp_path.append(system_name);
echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
Result := echo.read_word_in(tmp_file_read);
tmp_file_read.disconnect;
end;
feature {NONE}
singleton_memory: SYSTEM_TOOLS is
once
Result := Current;
end;
invariant
is_real_singleton: Current = singleton_memory
end -- SYSTEM_TOOLS